package mysql

import (
	"context"
	"errors"
	"go.uber.org/zap"
	"golang-sgg-daijia/internal/model"
	"gorm.io/gorm"
)

type PaymentInfoDao interface {
	Create(ctx context.Context, paymentInfo *model.PaymentInfo) error
	FindByID(ctx context.Context, id int64) (*model.PaymentInfo, error)
	FindByOrderNo(ctx context.Context, orderNo string) (*model.PaymentInfo, error)
	UpdateByID(ctx context.Context, paymentInfo *model.PaymentInfo) (int64, error)
}

func NewPaymentInfoDao(
	r *MysqlClient,
) PaymentInfoDao {
	return &paymentInfoDao{
		MysqlClient: r,
	}
}

type paymentInfoDao struct {
	*MysqlClient
}

func (r *paymentInfoDao) FindByOrderNo(ctx context.Context, orderNo string) (*model.PaymentInfo, error) {
	paymentInfo := &model.PaymentInfo{}
	if err := r.DB(ctx).Where("order_no = ?", orderNo).First(paymentInfo).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		r.logger.WithContext(ctx).Error("paymentInfoDao|GetByID", zap.Error(err))
		return nil, err
	}
	return paymentInfo, nil
}

func (r *paymentInfoDao) Create(ctx context.Context, paymentInfo *model.PaymentInfo) error {
	if err := r.DB(ctx).Create(paymentInfo).Error; err != nil {
		r.logger.WithContext(ctx).Error("paymentInfoDao|Create", zap.Error(err))
		return err
	}
	return nil
}

func (r *paymentInfoDao) FindByID(ctx context.Context, id int64) (*model.PaymentInfo, error) {
	paymentInfo := &model.PaymentInfo{}
	if err := r.DB(ctx).Where("id = ?", id).First(paymentInfo).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		r.logger.WithContext(ctx).Error("paymentInfoDao|GetByID", zap.Error(err))
		return nil, err
	}
	return paymentInfo, nil
}

func (r *paymentInfoDao) UpdateByID(ctx context.Context, paymentInfo *model.PaymentInfo) (int64, error) {
	db := r.DB(ctx).Where("id = ?", paymentInfo.ID).Updates(paymentInfo)
	n, err := db.RowsAffected, db.Error
	if err != nil {
		r.logger.WithContext(ctx).Error("paymentInfoDao|UpdateByID", zap.Error(err))
		return 0, err
	}
	return n, nil
}